@page "/profile"
@inherits ComponentBase
@using System.Linq

<div class="profile-shell">
    <MudGrid Class="profile-grid" GutterSize="2">
        <MudItem xs="12" sm="5" lg="4">
            <MudCard Outlined>
                <MudCardContent Style="padding:0px!important">
                    <div class="d-flex justify-center mb-4">
                        @if (!string.IsNullOrWhiteSpace(_avatarPreview ?? _profile.ImageUrl))
                        {
                            <MudAvatar Style=" width:100%;height:auto;border-radius:0px!important;">
                                <MudImage Src="@(_avatarPreview ?? _profile.ImageUrl)" Alt="@_profile.FirstName" />
                            </MudAvatar>
                        }
                        else
                        {
                            <MudAvatar Square="true" Color="Color.Surface" Style="width:100%;height:300px;">@_initials</MudAvatar>
                        }
                    </div>
                    <MudText Typo="Typo.h6" Align="Align.Center">@_profile.FirstName @_profile.LastName</MudText>
                    <MudText Align="Align.Center">@_profile.Email</MudText>
                </MudCardContent>
                <MudCardActions Class="d-flex justify-center">
                    <MudFileUpload T="IBrowserFile"
                                   OnFilesChanged="HandleFileChange"
                                   Accept="image/*"
                                   Disabled="_isUploading">
                        <ActivatorContent>
                            <MudButton Variant="Variant.Filled"
                                       Color="Color.Primary"
                                       DropShadow="false" 
                                       Size="Size.Small"
                                       StartIcon="@Icons.Material.Filled.CloudUpload">
                                Upload Image
                            </MudButton>
                        </ActivatorContent>
                    </MudFileUpload>
                    @if (!string.IsNullOrEmpty(_profile.ImageUrl))
                    {
                        <MudButton HtmlTag="label" DropShadow="false" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small" Target="_blank"
                                   StartIcon="@Icons.Material.Filled.RemoveRedEye" Href="@_profile.ImageUrl" Style="margin-left: 5px;">
                            View
                        </MudButton>

                        <MudButton HtmlTag="label" DropShadow="false" Variant="Variant.Filled" Color="Color.Error" Size="Size.Small"
                                   StartIcon="@Icons.Material.Filled.Delete" Style="margin-left: 5px;">
                            Delete
                        </MudButton>
                    }
                </MudCardActions>
            </MudCard>
        </MudItem>

        <MudItem xs="12" sm="7" lg="8">
            <MudPaper Class="profile-card pa-4 mb-4">
                <div class="profile-card__header">
                    <MudText Typo="Typo.h6">Profile</MudText>
                    <MudText Typo="Typo.caption" Color="Color.Secondary">Edit your personal details.</MudText>
                </div>
                <MudForm @ref="_form" Model="@_profile" OnValidSubmit="SaveProfile" OnInvalidSubmit="OnInvalidProfile">
                    <MudGrid>
                        <MudItem xs="12" sm="6">
                            <MudTextField @bind-Value="_profile.FirstName"
                                          Label="First Name"
                                          Required="true"
                                          Variant="Variant.Outlined" />
                        </MudItem>
                        <MudItem xs="12" sm="6">
                            <MudTextField @bind-Value="_profile.LastName"
                                          Label="Last Name"
                                          Required="true"
                                          Variant="Variant.Outlined" />
                        </MudItem>
                        <MudItem xs="12" sm="6">
                            <MudTextField @bind-Value="_profile.Email"
                                          Label="Email"
                                          Disabled="true"
                                          Variant="Variant.Outlined" />
                        </MudItem>
                        <MudItem xs="12" sm="6">
                            <MudTextField @bind-Value="_profile.PhoneNumber"
                                          Label="Phone"
                                          Variant="Variant.Outlined"
                                          HelperText="Optional. Include country code if needed." />
                        </MudItem>
                    </MudGrid>
                    <MudStack Row="true" Spacing="2" Class="mt-3 profile-actions">
                        <MudButton Color="Color.Primary"
                                   Variant="Variant.Filled"
                                   ButtonType="ButtonType.Submit"
                                   Disabled="_isSavingProfile"
                                   Loading="_isSavingProfile">
                            Save changes
                        </MudButton>
                        <MudButton Color="Color.Secondary" Variant="Variant.Outlined" OnClick="ReloadProfile" Disabled="_isSavingProfile">
                            Reset
                        </MudButton>
                    </MudStack>
                </MudForm>
            </MudPaper>

            <MudPaper Class="profile-card pa-4">
                <div class="profile-card__header">
                    <MudText Typo="Typo.h6">Change Password</MudText>
                    <MudText Typo="Typo.caption" Color="Color.Secondary">Use a strong, unique password.</MudText>
                </div>
                <MudForm @ref="_passwordForm" OnValidSubmit="ChangePassword" OnInvalidSubmit="OnInvalidPassword">
                    <MudGrid>
                        <MudItem xs="12" sm="4">
                            <MudTextField @bind-Value="_passwordModel.CurrentPassword"
                                          Label="Current Password"
                                          InputType="InputType.Password"
                                          Required="true"
                                          Variant="Variant.Outlined" />
                        </MudItem>
                        <MudItem xs="12" sm="4">
                            <MudTextField @bind-Value="_passwordModel.NewPassword"
                                          Label="New Password"
                                          InputType="InputType.Password"
                                          Required="true"
                                          Variant="Variant.Outlined"
                                          HelperText="Min 6 chars." />
                        </MudItem>
                        <MudItem xs="12" sm="4">
                            <MudTextField @bind-Value="_passwordModel.ConfirmPassword"
                                          Label="Confirm Password"
                                          InputType="InputType.Password"
                                          Required="true"
                                          Variant="Variant.Outlined" />
                        </MudItem>
                    </MudGrid>
                    <MudStack Row="true" Spacing="2" Class="mt-3 profile-actions">
                        <MudButton Color="Color.Primary"
                                   Variant="Variant.Filled"
                                   ButtonType="ButtonType.Submit"
                                   Disabled="_isChangingPassword"
                                   Loading="_isChangingPassword">
                            Update password
                        </MudButton>
                        <MudButton Color="Color.Secondary" Variant="Variant.Outlined" Disabled="_isChangingPassword" OnClick="@(() => _passwordModel = new())">
                            Clear
                        </MudButton>
                    </MudStack>
                </MudForm>
            </MudPaper>
        </MudItem>
    </MudGrid>
</div>

@code {
    private MudForm? _form;
    private MudForm? _passwordForm;
    private ProfileModel _profile = new();
    private PasswordDto _passwordModel = new();
    private string? _avatarPreview;
    private bool _isSavingProfile;
    private bool _isUploading;
    private bool _isChangingPassword;
    [Inject] private FSH.Playground.Blazor.ApiClient.IIdentityClient IdentityClient { get; set; } = default!;
    [Inject] private ISnackbar Snackbar { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        await ReloadProfile();
    }

    private async Task HandleFileChange(InputFileChangeEventArgs e)
    {
        var file = e.File;
        if (file is null) return;
        if (file.Size > 1_000_000)
        {
            Snackbar.Add("Image too large. Max 1 MB.", Severity.Error);
            return;
        }
        if (!file.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
        {
            Snackbar.Add("Only image uploads are allowed.", Severity.Error);
            return;
        }

        try
        {
            _isUploading = true;
            using var stream = file.OpenReadStream(1_000_000);
            using var memory = new MemoryStream();
            await stream.CopyToAsync(memory);
            var bytes = memory.ToArray().Select(b => (int)b).ToList();
            _avatarPreview = $"data:{file.ContentType};base64,{Convert.ToBase64String(memory.ToArray())}";

            if (string.IsNullOrWhiteSpace(_profile.Id) || string.IsNullOrWhiteSpace(_profile.Email))
            {
                Snackbar.Add("Profile not loaded yet.", Severity.Error);
                return;
            }

            var update = new FSH.Playground.Blazor.ApiClient.UpdateUserCommand
            {
                Id = _profile.Id,
                FirstName = _profile.FirstName ?? string.Empty,
                LastName = _profile.LastName ?? string.Empty,
                PhoneNumber = _profile.PhoneNumber ?? string.Empty,
                Email = _profile.Email,
                Image = new FSH.Playground.Blazor.ApiClient.FileUploadRequest
                {
                    FileName = file.Name,
                    ContentType = file.ContentType,
                    Data = bytes
                },
                DeleteCurrentImage = false
            };

            await IdentityClient.ProfilePutAsync(update);
            await ReloadProfile();
            Snackbar.Add("Profile image updated.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Failed to upload image: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isUploading = false;
            StateHasChanged();
        }
    }

    private async Task SaveProfile()
    {
        if (string.IsNullOrWhiteSpace(_profile.Id) || string.IsNullOrWhiteSpace(_profile.Email))
        {
            Snackbar.Add("Profile not loaded yet.", Severity.Error);
            return;
        }

        var request = new FSH.Playground.Blazor.ApiClient.UpdateUserCommand
        {
            Id = _profile.Id,
            FirstName = _profile.FirstName ?? string.Empty,
            LastName = _profile.LastName ?? string.Empty,
            PhoneNumber = _profile.PhoneNumber ?? string.Empty,
            Email = _profile.Email,
            DeleteCurrentImage = false
        };

        try
        {
            _isSavingProfile = true;
            await IdentityClient.ProfilePutAsync(request);
            await ReloadProfile();
            Snackbar.Add("Profile updated.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Failed to update profile: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isSavingProfile = false;
        }
    }

    private async Task ChangePassword()
    {
        if (!string.Equals(_passwordModel.NewPassword, _passwordModel.ConfirmPassword, StringComparison.Ordinal))
        {
            Snackbar.Add("New password and confirmation do not match.", Severity.Error);
            return;
        }

        var req = new FSH.Playground.Blazor.ApiClient.ChangePasswordCommand
        {
            Password = _passwordModel.CurrentPassword ?? string.Empty,
            NewPassword = _passwordModel.NewPassword ?? string.Empty,
            ConfirmNewPassword = _passwordModel.ConfirmPassword ?? string.Empty
        };

        try
        {
            _isChangingPassword = true;
            await IdentityClient.ChangePasswordAsync(req);
            Snackbar.Add("Password updated.", Severity.Success);
            _passwordModel = new();
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Failed to update password: {ex.Message}", Severity.Error);
        }
        finally
        {
            _isChangingPassword = false;
        }
    }

    private async Task ReloadProfile()
    {
        try
        {
            var response = await IdentityClient.ProfileGetAsync();
            _profile = response is null
                ? new ProfileModel()
                : new ProfileModel
                {
                    Id = response.Id ?? string.Empty,
                    FirstName = response.FirstName,
                    LastName = response.LastName,
                    Email = response.Email,
                    PhoneNumber = response.PhoneNumber,
                    ImageUrl = response.ImageUrl
                };
            _avatarPreview = null;
        }
        catch (Exception ex)
        {
            Snackbar.Add($"Failed to load profile: {ex.Message}", Severity.Error);
        }
    }

    private void OnInvalidProfile() => Snackbar.Add("Please correct the highlighted fields.", Severity.Error);
    private void OnInvalidPassword() => Snackbar.Add("Please complete all password fields.", Severity.Error);

    private string _initials =>
        string.Concat(
            (_profile.FirstName ?? string.Empty).Take(1),
            (_profile.LastName ?? string.Empty).Take(1)).ToUpperInvariant();

    private sealed class ProfileModel
    {
        public string Id { get; set; } = string.Empty;
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public string? Email { get; set; }
        public string? PhoneNumber { get; set; }
        public string? ImageUrl { get; set; }
    }

    private sealed class PasswordDto
    {
        public string? CurrentPassword { get; set; }
        public string? NewPassword { get; set; }
        public string? ConfirmPassword { get; set; }
    }
}
